package com.wy2.eclipse.tool.ui.editors;


import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.MultiPageEditorPart;
import org.eclipse.wst.sse.ui.StructuredTextEditor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.wy2.core.PropertiesDocument;
import com.wy2.core.common.EncodingConsts;
import com.wy2.core.date.DateTime;
import com.wy2.core.tool.JsonTools;
import com.wy2.core.tool.StringTools;
import com.wy2.eclipse.tool.lib.ProjectConfigManager;
import com.wy2.eclipse.tool.lib.TemplateConfigManager;
import com.wy2.eclipse.tool.lib.common.Constants;
import com.wy2.eclipse.tool.lib.common.IDEUtils;
import com.wy2.eclipse.tool.lib.entity.CodeGenerateInfo;
import com.wy2.eclipse.tool.lib.entity.TableModuleConfig;
import com.wy2.eclipse.tool.lib.entity.TemplateConfig;
import com.wy2.eclipse.tool.lib.entity.TemplateItem;
import com.wy2.eclipse.tool.ui.UIActivator;
import com.wy2.eclipse.tool.ui.dialog.DatabaseConfigDialog;
import com.wy2.generator.GenerateResult;
import com.wy2.generator.GeneratorByJdbcConnection;
import com.wy2.generator.config.GeneratorConsts;
import com.wy2.generator.database.common.DatabaseMetaDataEntity;
import com.wy2.generator.database.entity.DatabaseColumn;
import com.wy2.generator.database.entity.DatabaseTable;

/**
 * An example showing how to create a multi-page editor.
 * This example has 3 pages:
 * <ul>
 * <li>page 0 contains a nested text editor.
 * <li>page 1 allows you to change the font used in page 2
 * <li>page 2 shows the words in page 0 in sorted order
 * </ul>
 */
public class CodeGenerateEditor extends MultiPageEditorPart implements IResourceChangeListener{
    
    private static final Logger logger=LoggerFactory.getLogger(CodeGenerateEditor.class);

	/** The text editor used in page 0. */
    private ComboViewer comboViewerTemplateName;
    private Text textPackage;
    private CheckboxTreeViewer treeViewer;
    private Label lbTableState;

	/** The font chosen in page 1. */

	private StructuredTextEditor editor;
	
	/**
	 * 项目配置管理
	 */
	private ProjectConfigManager projectConfigManager=null;
	public ProjectConfigManager getProjectConfigManager() {
	    if(projectConfigManager==null) {
	        if(editor.getEditorInput() instanceof FileEditorInput) {
	            FileEditorInput fileEditor=(FileEditorInput) editor.getEditorInput();
	            String generateConfigFileRelativePath=fileEditor.getFile().getProjectRelativePath().toOSString();
	            projectConfigManager=new ProjectConfigManager(fileEditor.getFile().getProject(),generateConfigFileRelativePath);
	        }else {
	            logger.error("参数不正确，无法初始化项目配置管理器");
	        }
	    }
	    return projectConfigManager;
	}

	/**
	 * Creates a multi-page editor example.
	 */
	public CodeGenerateEditor() {
		super();
		ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
	}
	
	/**
     * Creates page 0 of the multi-page editor,
     * which allows you to change the font used in page 2.
     */
    void createPage0() {

        Composite composite = new Composite(getContainer(), SWT.NONE);
        composite.setLayout(new FillLayout(SWT.HORIZONTAL));
        {
            SashForm sashForm = new SashForm(composite, SWT.NONE);
            {
                Group group = new Group(sashForm, SWT.NONE);
                group.setText("配置");
                GridLayout gridLayout = new GridLayout(5, true);
                gridLayout.marginWidth=5;
                group.setLayout(gridLayout);
                {
                    Label lblNewLabel = new Label(group, SWT.NONE);
                    lblNewLabel.setText("选择生成模板");
                    GridData gd = new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1);
                    lblNewLabel.setLayoutData(gd);
                }
                {

                    comboViewerTemplateName = new ComboViewer(group, SWT.NONE | SWT.READ_ONLY);
                    Combo comboTemplateName = comboViewerTemplateName.getCombo();
                    comboTemplateName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 4, 1));
                    comboViewerTemplateName.setContentProvider(new CodeTemplateContentProvider());
                    comboViewerTemplateName.setLabelProvider(new CodeTemplateLabelProvider());
                    
                    
                    
                }
                {
                    Label lblNewLabel_1 = new Label(group, SWT.NONE);
                    lblNewLabel_1.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
                    lblNewLabel_1.setText("包名");
                }
                {
                    textPackage = new Text(group, SWT.BORDER | SWT.READ_ONLY);
                    textPackage.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 4, 1));
                }
                {
                    Label lblNewLabel_2 = new Label(group, SWT.NONE);
                    lblNewLabel_2.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
                    lblNewLabel_2.setText("选择要生成的表");
                    
                    lbTableState = new Label(group, SWT.NONE);
                    lbTableState.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false, 4, 1));
                    lbTableState.setText("选中1张表/共2张表");
                }
                {
                    treeViewer = new CheckboxTreeViewer(group, SWT.CHECK | SWT.FULL_SELECTION);
                    Tree tree = treeViewer.getTree();
                    tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 5, 1));
                    tree.setLinesVisible(true);
                    tree.setHeaderVisible(true);
                    
                    treeViewer.addCheckStateListener(new ICheckStateListener() {
                        
                        @Override
                        public void checkStateChanged(CheckStateChangedEvent event) {
                            if(event.getElement() instanceof DatabaseTable) {
                                DatabaseTable databaseTable= (DatabaseTable)event.getElement();
                                databaseTable.setChecked(event.getChecked());
                                if(databaseTable.getChecked()) {
                                    databaseTable.checkedAll(true);
                                }else {
                                    databaseTable.checkedAll(false);
                                }
                            }else if(event.getElement() instanceof DatabaseColumn) {
                                DatabaseColumn databaseColumn= (DatabaseColumn)event.getElement();
                                databaseColumn.setChecked(event.getChecked());
                                if(databaseColumn.getChecked()) {
                                    databaseColumn.getTable().setChecked(true);
                                }
                            }
                            Display.getDefault().syncExec(new Runnable() {
                                
                                @Override
                                public void run() {
                                    treeViewer.refresh();
                                    Map<Integer, Integer> state = getstate();
                                    showState(state.get(0),state.get(1));
                                }
                            });
                            
                            
                        }
                    });
                    
                    

                    
                    TreeColumn treeColumn = new TreeColumn(tree, SWT.NONE);
                    treeColumn.setWidth(300);
                    treeColumn.setText("表名/字段名");
                    
                    TreeColumn treeColumn_1 = new TreeColumn(tree, SWT.NONE);
                    treeColumn_1.setWidth(160);
                    treeColumn_1.setText("实体名/字段属性名");
                    
                    TreeColumn treeColumn_2 = new TreeColumn(tree, SWT.NONE);
                    treeColumn_2.setWidth(200);
                    treeColumn_2.setText("字段属性类型");
                    
                    TreeColumn treeColumn_3 = new TreeColumn(tree, SWT.NONE);
                    treeColumn_3.setWidth(200);
                    treeColumn_3.setText("模块");
                    
                    treeViewer.setContentProvider(new TableContentProvider());
                    treeViewer.setLabelProvider(new TableLabelProvider());
                    treeViewer.setCheckStateProvider(new TableCheckStateProvider());
                    
                    
                    modifyTable();
                    
                    
                }
            }
            {
                Group group = new Group(sashForm, SWT.NONE);
                group.setText("操作");
                GridLayout gridLayout = new GridLayout(1, false);
                gridLayout.marginWidth=20;
                gridLayout.verticalSpacing=10;
                group.setLayout(gridLayout);
                
                Button btnLoadTables = new Button(group, SWT.NONE);
                btnLoadTables.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
                btnLoadTables.setText("刷新表信息");
                btnLoadTables.addSelectionListener(new SelectionAdapter() {
                    /** 
                     * @param e 
                     * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
                     */
                    @Override
                    public void widgetSelected(SelectionEvent e) {
                        final CodeGenerateInfo codeGenerateInfo = getProjectConfigManager().loadCodeGenerateInfo();
                        loadTables(true,codeGenerateInfo!=null ? codeGenerateInfo.getTables() : null);
                    }
                });
                
                
                
                Button btnGenerate = new Button(group, SWT.NONE);
                btnGenerate.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
                btnGenerate.setText("开始生成");
                btnGenerate.addSelectionListener(new SelectionAdapter() {
                    /** 
                     * @param e 
                     * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
                     */
                    @Override
                    public void widgetSelected(SelectionEvent e) {
                       generate();
                    }
                });
                Button btnDelete = new Button(group, SWT.NONE);
                btnDelete.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
                btnDelete.setText("删除生成文件");
                btnDelete.addSelectionListener(new SelectionAdapter() {
                    /** 
                     * @param e 
                     * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
                     */
                    @Override
                    public void widgetSelected(SelectionEvent e) {
                        delete();
                    }
                });
                
                Button btnTestConnection = new Button(group, SWT.NONE);
                btnTestConnection.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
                btnTestConnection.setText("测试数据连接");
                btnTestConnection.addSelectionListener(new SelectionAdapter() {
                    /** 
                     * @param e 
                     * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
                     */
                    @Override
                    public void widgetSelected(SelectionEvent e) {
                        Display.getDefault().syncExec(new Runnable() {                
                            @Override
                            public void run() {
                                DatabaseConfigDialog dbConfigDialog=new DatabaseConfigDialog(getWorkbenchWindow().getShell(),
                                        getProject(),
                                        getProjectConfigManager().getGenerateConfigFile());
                                dbConfigDialog.open();
                            }
                        });
                        
                    }
                });
                
                Label labelSEPARATOR = new Label(group, SWT.SEPARATOR | SWT.HORIZONTAL);
                labelSEPARATOR.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
                
                Button btnAllSelected = new Button(group, SWT.NONE);
                btnAllSelected.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
                btnAllSelected.setText("全选");
                btnAllSelected.addSelectionListener(new SelectionAdapter() {
                    /** 
                     * @param e 
                     * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
                     */
                    @Override
                    public void widgetSelected(SelectionEvent e) {
                        
                        Display.getDefault().syncExec(new Runnable() {                
                            @Override
                            public void run() {
                                allSelected(true);
                            }
                        });
                    }
                });
                
                
                Button btnAllUnSelected = new Button(group, SWT.NONE);
                btnAllUnSelected.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
                btnAllUnSelected.setText("全不选");
                btnAllUnSelected.addSelectionListener(new SelectionAdapter() {
                    /** 
                     * @param e 
                     * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
                     */
                    @Override
                    public void widgetSelected(SelectionEvent e) {
                        
                        Display.getDefault().syncExec(new Runnable() {                
                            @Override
                            public void run() {
                                allSelected(false);
                            }
                        });
                    }
                });
                
                Button btnCollapseAll = new Button(group, SWT.NONE);
                btnCollapseAll.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
                btnCollapseAll.setText("全折叠");
                btnCollapseAll.addSelectionListener(new SelectionAdapter() {
                    /** 
                     * @param e 
                     * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
                     */
                    @Override
                    public void widgetSelected(SelectionEvent e) {
                        Display.getDefault().syncExec(new Runnable() {                
                            @Override
                            public void run() {
                                treeViewer.collapseAll();
                            }
                        });
                        
                    }
                });
                Button btnExpandAll = new Button(group, SWT.NONE);
                btnExpandAll.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
                btnExpandAll.setText("全展开");
                btnExpandAll.addSelectionListener(new SelectionAdapter() {
                    /** 
                     * @param e 
                     * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
                     */
                    @Override
                    public void widgetSelected(SelectionEvent e) {
                        Display.getDefault().syncExec(new Runnable() {                
                            @Override
                            public void run() {
                                expandAll();
                            }
                        });
                        
                    }
                });
                
                
                
            }
            int compositeH = 180; // 组件固定高度  
            Point p =sashForm.getSize();  
            sashForm.setWeights(new int[] {8, 2});
            sashForm.SASH_WIDTH=0;
            sashForm.addControlListener(new ControlListener() {  
                          
                @Override  
                public void controlResized(ControlEvent e) {
                    Display.getDefault().syncExec(new Runnable() {                
                        @Override
                        public void run() {
                            Point p =sashForm.getSize();  
                            sashForm.setWeights(new int[]{p.x-compositeH, compositeH}); // 这里是关键
                        }
                    });

                      
                }  
                          
                @Override  
                public void controlMoved(ControlEvent e) {}  
            }); 
            
        }

        int index = addPage(composite);
        setPageText(index, "生成操作");
    }
    
    /**
     * 树表修改处理
     */
    private void modifyTable() {
        
        treeViewer.setColumnProperties(new String[] {TableCellModifier.COLUMN_0,TableCellModifier.COLUMN_1, TableCellModifier.COLUMN_2, TableCellModifier.COLUMN_3});
        treeViewer.setCellModifier(new TableCellModifier(treeViewer));
        
        CellEditor[] CellEditors=new CellEditor[4];
        CellEditors[0]=null;
        CellEditors[1]=null;
        CellEditors[2]=null;
        CellEditors[3]=new TextCellEditor(treeViewer.getTree());
        treeViewer.setCellEditors(CellEditors);
        //treeViewer.setCellModifier(new Tree);
    }
    
	/**
	 * Creates page1 of the multi-page editor,
	 * which contains a text editor.
	 */
	void createPage1() {
		try {
			editor = new StructuredTextEditor();
			int index = addPage(editor, getEditorInput());
			setPageText(index, "配置源文件");
			//editor.getTitle()
			this.setPartName(editor.getTitle());
		} catch (PartInitException e) {
			ErrorDialog.openError(
				getSite().getShell(),
				"Error creating nested text editor",
				null,
				e.getStatus());
		}
	}
	

	/**
	 * Creates the pages of the multi-page editor.
	 */
	protected void createPages() {
		createPage0();
		createPage1();
		
		final CodeGenerateInfo codeGenerateInfo = getProjectConfigManager().loadCodeGenerateInfo();
		File templateConfigFile=new File(UIActivator.getDefault().getTemplateRootDirectory(), Constants.CONFIG_TEMPLATE_CONFIG_FILE);
		TemplateConfigManager templateConfigManager=UIActivator.getDefault().getTemplateConfigManager();
		if(templateConfigFile.exists()) {
		    try {
                TemplateConfig templateConfig = templateConfigManager.loadTemplateConfig();
                if(templateConfig==null) {
                    throw new Exception("模板配置不正确或不存在");
                }
                comboViewerTemplateName.setInput(templateConfig);
                
                
                if(codeGenerateInfo==null) {
                    comboViewerTemplateName.getCombo().select(0);
                }else {
                    comboViewerTemplateName.setSelection(new StructuredSelection(codeGenerateInfo.getTemplateItem()));
                }
                
                
            } catch (Exception e) {
                logger.error("加载模板配置异常", e);
            }
		}
		
		
		
		//IEditorPart editor = getEditor(1);
		//editor.getEditorInput().
		reloadGenerateConfig();
		
		loadTables(false,codeGenerateInfo!=null ? codeGenerateInfo.getTables() : null);
	}
	
	/**
	 * 加载生成配置
	 */
	private void reloadGenerateConfig() {
		PropertiesDocument propDoc=getProjectConfigManager().loadGenerateConfig();
		if(propDoc!=null) {
		    textPackage.setText(propDoc.getProperty(GeneratorConsts.GENERATOR_CONFIG_TEMPLATE_ATTRIBUTE_PREFIX+"."+ GeneratorConsts.TEMPLATE_ATTRI_BASEPACKAGE));
		}
	}
	
	/**
	 * 得到编辑所在项目信息
	 * @return
	 */
	protected IProject getProject() {
	    if(editor.getEditorInput() instanceof FileEditorInput) {
            FileEditorInput fileEditor=(FileEditorInput) editor.getEditorInput();
            return fileEditor.getFile().getProject();
        }
        return null;
	}
	
	
	
	
	
	
	/**
	 * 加载表
	 * @param reload 是否从数据库重新加载
	 */
	private void loadTables(Boolean reload,List<DatabaseTable> lastGeneratetables) {
	    PropertiesDocument configDoc=getProjectConfigManager().loadGenerateConfig();
	    if(configDoc==null) {
	        logger.error("加载配置失败，无法加载表信息");
	        return;
	    }
	    File templateDirectory=new File(UIActivator.getDefault().getTemplateRootDirectory(),"codetest");
	    configDoc.setProperty(GeneratorConsts.GENERATOR_CONFIG_TEMPLATE_DIRECTORY, templateDirectory.getAbsolutePath());
	    configDoc.setProperty(GeneratorConsts.GENERATOR_CONFIG_OUTPUT_DIRECTORY, getProject().getLocation().toOSString());
	    GeneratorByJdbcConnection generatorByJdbcConnection=new GeneratorByJdbcConnection(configDoc);
	    
	    DatabaseMetaDataEntity databaseMetaDataEntity =getProjectConfigManager().loadDatabaseMetaData(reload);
	    if(databaseMetaDataEntity==null || databaseMetaDataEntity.getTables().isEmpty() || databaseMetaDataEntity.getTables().size()<1) {
	    	try {
	    		databaseMetaDataEntity = generatorByJdbcConnection.getDatabaseMetaDataEntity(null);
	    	}catch (Exception e) {
	    		logger.warn("没有加载到任何表信息，请确认数据库连接配置是否正常");
	            return;
			}
	        if(databaseMetaDataEntity==null || databaseMetaDataEntity.getTables().isEmpty()) {
	            logger.warn("没有加载到任何表信息，请确认数据库中有表，或检查网络是否正常");
	            return;
	        }
	        getProjectConfigManager().saveDatabaseMetaData(databaseMetaDataEntity);
	    }
	    
	    
	    //加载表模块信息
	    if(getProjectConfigManager().getTableModuleConfigFile().exists()) {
	        TableModuleConfig moduleConfig=getProjectConfigManager().loadTableModuleConfig();
	        if(moduleConfig!=null) {
	            for (DatabaseTable databaseTable : databaseMetaDataEntity.getTables()) {
                    if(moduleConfig.containsKey(databaseTable.getSqlName())) {
                        databaseTable.setModule(moduleConfig.get(databaseTable.getSqlName()));
                    }
                }
	        }
	        
	        
	    }
	    

	    
	    
	    if(lastGeneratetables!=null) {
	        int lastPos=-1;
	        DatabaseColumn lastColumn=null;
	        for (DatabaseTable databaseTable : databaseMetaDataEntity.getTables()) {
	            lastPos=lastGeneratetables.indexOf(databaseTable);
                if(lastPos>-1){
                    
                    databaseTable.setChecked(lastGeneratetables.get(lastPos).getChecked());
                    for (DatabaseColumn databaseColumn : databaseTable.getColumns()) {
                        lastColumn=lastGeneratetables.get(lastPos).getColumns().get(lastGeneratetables.get(lastPos).getColumns().indexOf(databaseColumn));
                        databaseColumn.setChecked(lastColumn.getChecked());
                    }
                }else {
                    databaseTable.setChecked(false);
                    databaseTable.checkedAll(false);
                }
            }
	        
	        final DatabaseMetaDataEntity databaseMetaDataEntity2=databaseMetaDataEntity;
	        Display.getDefault().syncExec(new Runnable() {
                
                @Override
                public void run() {
                    treeViewer.setInput(databaseMetaDataEntity2.getTables());
                    Map<Integer, Integer> state = getstate();
                    showState(state.get(0),state.get(1));
                }
            });
	        
	    }else {
	        final DatabaseMetaDataEntity databaseMetaDataEntity2=databaseMetaDataEntity;
            Display.getDefault().syncExec(new Runnable() {                
                @Override
                public void run() {
                    treeViewer.setInput(databaseMetaDataEntity2.getTables());
                    allSelected(true);
                    Map<Integer, Integer> state = getstate();
                    showState(state.get(0),state.get(1));
                }
            });
	        
	    }
	}
	
	/**
	 * 全选
	 * @param selected
	 */
	private void allSelected(Boolean selected) {
	    //TreeItem[] items = treeViewer.getTree().getItems();
	    
	    Object obj= treeViewer.getInput();
	    if(obj instanceof List) {
	        List objs=(List) obj;
	        for (Object object : objs) {
	            ((DatabaseTable)object).setChecked(selected);
	            ((DatabaseTable)object).checkedAll(selected);
            }
	    }
	    
	    treeViewer.refresh();
        
        Map<Integer, Integer> state = getstate();
        showState(state.get(0),state.get(1));
	}
	
	private void expandAll() {
	    treeViewer.expandAll();
//	    TreeItem[] items = treeViewer.getTree().getItems();
//        for (TreeItem treeItem : items) {
//            TreeItem[] columns = treeItem.getItems();
//            for (TreeItem treeItem2 : columns) {
//                treeItem2.setChecked(treeItem.getChecked());
//            }
//        }
        Map<Integer, Integer> state = getstate();
        showState(state.get(0),state.get(1));
	}
	
	/**
	 * 得到统计状态
	 * @return
	 */
	private Map<Integer,Integer> getstate(){
	    Map<Integer,Integer> stateMap=new HashMap<>();
	    int total=0;
	    int selectedCount=0;
        Tree tree=treeViewer.getTree();
        for (TreeItem treeItem : tree.getItems()) {
            total++;
            if(treeItem.getChecked()) {
                selectedCount++;
            }
        }
        stateMap.put(0, total);
        stateMap.put(1, selectedCount);
        return stateMap;
	}
	
	private List<DatabaseTable> getAllTables(){
        List<DatabaseTable> tables=new ArrayList<>();
        Tree tree=treeViewer.getTree();
        for (TreeItem treeItem : tree.getItems()) {
            tables.add((DatabaseTable)treeItem.getData());
        }
        return tables;
    }
	
	private List<DatabaseTable> getSelectedTables(){
	    List<DatabaseTable> tables=new ArrayList<>();
	    Tree tree=treeViewer.getTree();
	    for (TreeItem treeItem : tree.getItems()) {
	        if(treeItem.getChecked()) {
	            tables.add((DatabaseTable)treeItem.getData());
	        }
	    }
	    return tables;
	}
	
	/**
	 * 保存表模块配置
	 */
	private void saveTableModuleConfig() {
	    List<DatabaseTable>  allTables = getAllTables();
        TableModuleConfig moduleConfig=new TableModuleConfig();
        for (DatabaseTable databaseTable : allTables) {
            moduleConfig.put(databaseTable.getSqlName(), databaseTable.getModule());
        }
        getProjectConfigManager().saveTableModuleConfig(moduleConfig);
	}
	
	/**
	 * 生成代码
	 */
	private void generate() {
	    saveTableModuleConfig();
	    
        List<DatabaseTable> selectedTables = getSelectedTables();
        if(selectedTables==null || selectedTables.isEmpty() || selectedTables.size()<1) {
            logger.warn("没有需要生成的数据表...");
            Display.getDefault().syncExec(new Runnable() {
                
                @Override
                public void run() {
                    MessageDialog.openWarning(Display.getDefault().getActiveShell(), "操作提示", "没有需要生成的数据表...");
                }
            });
            return;
        }
        
        PropertiesDocument configDoc=getProjectConfigManager().loadGenerateConfig();
        if(configDoc==null) {
            logger.error("加载配置失败，无法加载表信息");
            return;
        }
        
        IStructuredSelection selection = comboViewerTemplateName.getStructuredSelection();
        if(selection.isEmpty() || !(selection.getFirstElement() instanceof TemplateItem)) {
            logger.error("生成代码异常，原因是：没有选择生成模板。");
            return;
        }
        String basePackage=textPackage.getText().trim();
        if(StringTools.isEmpty(basePackage)) {
            logger.error("生成代码异常，原因是：没有输入包名。");
            return;
        }
        
        TemplateItem templateItem=(TemplateItem) selection.getFirstElement();
        String templateFolder=templateItem.getTemplateFolder();
        
        
        
        CodeGenerateInfo codeGenerateInfo=new CodeGenerateInfo();
        codeGenerateInfo.setGenerateTime(DateTime.Now().getDate());
        codeGenerateInfo.setBasePackage(basePackage);
        codeGenerateInfo.setTemplateItem(templateItem);
        codeGenerateInfo.setTables(selectedTables);
        
        CodeGenerateInfo oldCodeGenerateInfo=getProjectConfigManager().loadCodeGenerateInfo();
        if(oldCodeGenerateInfo!=null) {
            for (String generateTable : oldCodeGenerateInfo.getGeneratedTables()) {
                codeGenerateInfo.addGeneratedTable(generateTable);
            }
        }
        for (DatabaseTable databaseTable : selectedTables) {
            //codeGenerateInfo.addTable(databaseTable.getSqlName());
            codeGenerateInfo.addGeneratedTable(databaseTable.getSqlName());
        }
        getProjectConfigManager().saveCodeGenerateInfo(codeGenerateInfo);
        
        
        File templateDirectory=new File(UIActivator.getDefault().getTemplateRootDirectory(),templateFolder);
        configDoc.setProperty(GeneratorConsts.GENERATOR_CONFIG_TEMPLATE_DIRECTORY, templateDirectory.getAbsolutePath());
        configDoc.setProperty(GeneratorConsts.GENERATOR_CONFIG_OUTPUT_DIRECTORY, getProject().getLocation().toFile().getParentFile().getAbsolutePath());
        GeneratorByJdbcConnection generatorByJdbcConnection=new GeneratorByJdbcConnection(configDoc);

                
        Map<String,Object> model=new HashMap<>();
        model.put(GeneratorConsts.TEMPLATE_ATTRI_PROJECT_NAME,getProject().getName());
        model.put(GeneratorConsts.TEMPLATE_ATTRI_ARTIFACT_ID,getProject().getName());
        model.put(GeneratorConsts.TEMPLATE_ATTRI_BASEPACKAGE, basePackage);
        
        LinkedList<GenerateResult> generateResults = generatorByJdbcConnection.generteByTables(selectedTables, model, true);
        
        IDEUtils.refreshProject(getProject());
        
        logger.info("{}",generatorByJdbcConnection.getOutputRootDirectory());
        generateResults.forEach(result->{
            logger.info("{} - {} - {}",result.getMarker(),result.getSuccess(),result.getGenerateFilePath());
        });
        
        Display.getDefault().syncExec(new Runnable() {
            
            @Override
            public void run() {
                MessageDialog.openInformation(Display.getDefault().getActiveShell(), "操作提示", "代码生成成功");
            }
        });
	}
	
	/**
	 * 删除
	 */
	private void delete() {
	    logger.info("删除生成代码...");
        saveTableModuleConfig();
        
        List<DatabaseTable> selectedTables = getSelectedTables();
        if(selectedTables==null || selectedTables.isEmpty() || selectedTables.size()<1) {
            logger.warn("没有需要生成的数据表...");
            Display.getDefault().syncExec(new Runnable() {
                
                @Override
                public void run() {
                    MessageDialog.openWarning(Display.getDefault().getActiveShell(), "操作提示", "没有需要生成的数据表...");
                }
            });
            return;
        }
        
        PropertiesDocument configDoc=getProjectConfigManager().loadGenerateConfig();
        if(configDoc==null) {
            logger.error("加载配置失败，无法加载表信息");
            return;
        }
        
        IStructuredSelection selection = comboViewerTemplateName.getStructuredSelection();
        if(selection.isEmpty() || !(selection.getFirstElement() instanceof TemplateItem)) {
            logger.error("生成代码异常，原因是：没有选择生成模板。");
            return;
        }
        
        TemplateItem templateItem=(TemplateItem) selection.getFirstElement();
        String templateFolder=templateItem.getTemplateFolder();
        
        File templateDirectory=new File(UIActivator.getDefault().getTemplateRootDirectory(),templateFolder);
        configDoc.setProperty(GeneratorConsts.GENERATOR_CONFIG_TEMPLATE_DIRECTORY, templateDirectory.getAbsolutePath());
        configDoc.setProperty(GeneratorConsts.GENERATOR_CONFIG_OUTPUT_DIRECTORY, getProject().getLocation().toFile().getParentFile().getAbsolutePath());
        GeneratorByJdbcConnection generatorByJdbcConnection=new GeneratorByJdbcConnection(configDoc);

                
        Map<String,Object> model=new HashMap<>();
        model.put(GeneratorConsts.TEMPLATE_ATTRI_PROJECT_NAME,getProject().getName());
        model.put(GeneratorConsts.TEMPLATE_ATTRI_ARTIFACT_ID,getProject().getName());
        model.put(GeneratorConsts.TEMPLATE_ATTRI_BASEPACKAGE, textPackage.getText().trim());
        
        LinkedList<GenerateResult> generateResults = generatorByJdbcConnection.getGenerateFiles(selectedTables, model);
        
        
        
        
        logger.info("{}",generatorByJdbcConnection.getOutputRootDirectory());
        generateResults.forEach(result->{
            File file=new File(generatorByJdbcConnection.getOutputRootDirectory(), result.getGenerateFilePath());
            if(file.exists() && file.isFile()) {
                file.delete();
            }
            logger.info("delete: {} - {} - {}",result.getMarker(),result.getSuccess(),result.getGenerateFilePath());
        });
        IDEUtils.refreshProject(getProject());
        
        Display.getDefault().syncExec(new Runnable() {
            
            @Override
            public void run() {
                MessageDialog.openInformation(Display.getDefault().getActiveShell(), "操作提示", "删除生成代码成功");
            }
        });
	}
	
	private void showState(int total,int selectedCount) {
	    lbTableState.setText(MessageFormat.format("选中 {1} 张表 / 共 {0} 张表", total,selectedCount));
	}
	
	/**
	 * The <code>MultiPageEditorPart</code> implementation of this 
	 * <code>IWorkbenchPart</code> method disposes all nested editors.
	 * Subclasses may extend.
	 */
	public void dispose() {
		ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
		super.dispose();
	}
	/**
	 * Saves the multi-page editor's document.
	 */
	public void doSave(IProgressMonitor monitor) {
		getEditor(1).doSave(monitor);
		reloadGenerateConfig();
	}
	/**
	 * Saves the multi-page editor's document as another file.
	 * Also updates the text for page 0's tab, and updates this multi-page editor's input
	 * to correspond to the nested editor's.
	 */
	public void doSaveAs() {
		IEditorPart editor = getEditor(1);
		editor.doSaveAs();
		
		reloadGenerateConfig();
		
		setPageText(1, editor.getTitle());
		setInput(editor.getEditorInput());
	}
	/* (non-Javadoc)
	 * Method declared on IEditorPart
	 */
	public void gotoMarker(IMarker marker) {
		setActivePage(0);
		IDE.gotoMarker(getEditor(0), marker);
	}
	/**
	 * The <code>MultiPageEditorExample</code> implementation of this method
	 * checks that the input is an instance of <code>IFileEditorInput</code>.
	 */
	public void init(IEditorSite site, IEditorInput editorInput)
		throws PartInitException {
		if (!(editorInput instanceof IFileEditorInput))
			throw new PartInitException("Invalid Input: Must be IFileEditorInput");
		super.init(site, editorInput);
	}
	/* (non-Javadoc)
	 * Method declared on IEditorPart.
	 */
	public boolean isSaveAsAllowed() {
		return true;
	}
	/**
	 * Calculates the contents of page 2 when the it is activated.
	 */
	protected void pageChange(int newPageIndex) {
		super.pageChange(newPageIndex);
	}
	/**
	 * Closes all project files on project close.
	 */
	public void resourceChanged(final IResourceChangeEvent event){
		if(event.getType() == IResourceChangeEvent.PRE_CLOSE){
			Display.getDefault().asyncExec(new Runnable(){
				public void run(){
					IWorkbenchPage[] pages = getSite().getWorkbenchWindow().getPages();
					for (int i = 0; i<pages.length; i++){
						if(((FileEditorInput)editor.getEditorInput()).getFile().getProject().equals(event.getResource())){
							IEditorPart editorPart = pages[i].findEditor(editor.getEditorInput());
							pages[i].closeEditor(editorPart,true);
						}
					}
				}            
			});
		}
	}

	
	public IWorkbenchWindow getWorkbenchWindow() {
	    return this.getSite().getWorkbenchWindow();
	}

}
